#include "mmStrMatch.h"

static PyObject* wildcardMatch(PyObject *self, PyObject *args)
{
	int status;
	const char *str;
	const char *pattern;
	
	//printf("nStatCnt = %i\n", nStatCnt++);

	if (!PyArg_ParseTuple(args, "ss", &pattern, &str))
		return NULL;

	//printf("text = %s\n", str);

	status = fnmatch(pattern, str, FNM_PERIOD);

	if (status != 0)
	{
		Py_RETURN_FALSE;
	}
	Py_RETURN_TRUE;
}

static PyObject* regExpMatch(PyObject *self, PyObject *args)
{
	int status;
	const char *str;
	const char *pattern = NULL;
	static char histPattern[MAX_PATTERN_LEN];
	static regex_t re;

	if (!PyArg_ParseTuple(args, "ss", &pattern, &str))
		return NULL;
	
	if (cmpPattern(pattern, histPattern) != 0)
	{
		//printf("Regexp to be compiled...   ");
		regfree(&re);
		if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB) != 0) 
		{
			//printf("[FAILED]\n");
			Py_RETURN_FALSE;
		}
		resetBuffer(histPattern, MAX_PATTERN_LEN);
		//printf("[OK]\n");
	}

	memcpy(histPattern, pattern, strlen(pattern));

	status = regexec(&re, str, (size_t) 0, NULL, 0);

	if (status != 0) 
	{
		Py_RETURN_FALSE;
	}
	Py_RETURN_TRUE;
}
 
static PyObject* camelCaseMatch(PyObject *self, PyObject *args)
{
	int status;
	const char *str;
	const char *pattern = NULL;
	static char histPattern[MAX_PATTERN_LEN];
	static regex_t re;

	if (!PyArg_ParseTuple(args, "ss", &pattern, &str))
		return NULL;
	
	if (cmpPattern(pattern, histPattern) != 0)
	{
		//printf("Regexp to be compiled...   ");
		regfree(&re);
		if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB) != 0) 
		{
			//printf("[FAILED]\n");
			Py_RETURN_FALSE;
		}
		resetBuffer(histPattern, MAX_PATTERN_LEN);
		//printf("[OK]\n");
	}

	memcpy(histPattern, pattern, strlen(pattern));

	status = regexec(&re, str, (size_t) 0, NULL, 0);

	if (status != 0) 
	{
		Py_RETURN_FALSE;
	}
	Py_RETURN_TRUE;
}

static PyMethodDef mmStrMatchMethods[] = {
	{"wildcard", wildcardMatch, METH_VARARGS, "Do a wildcard compare for given pattern and string."},
	{"regExp", regExpMatch, METH_VARARGS, "Do a regular expression compare for given pattern and string."},
	{"camelCase", camelCaseMatch, METH_VARARGS, "Do a camel case expression compare for given pattern and string."}
	//{NULL, NULL, 0, NULL}
};
 
PyMODINIT_FUNC initmmStrMatch(void)
{
	(void) Py_InitModule("mmStrMatch", mmStrMatchMethods);
}

int cmpPattern(const char *pat1, const char *pat2)
{
	int nLen1, nLen2, nCmpRes;

	nLen1 = strlen(pat1);
	nLen2 = strlen(pat2);
	
	//printf("pat1 (%i) = %s\n", nLen1, pat1);
	//printf("pat2 (%i) = %s\n", nLen2, pat2);

	if (pat1 == NULL || pat2 == NULL)
	{
		return -1;
	}

	if (nLen1 != nLen2)
	{
		return 1;
	}

	nCmpRes = memcmp(pat1, pat2, nLen1);
	return nCmpRes;
}

void resetBuffer(char *buff, int nLen)
{
	memset(buff, '\0', nLen);
}
